﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Xml.Serialization;
using System.ComponentModel;

namespace BDSim
{
    //Add by ZLY
    #region 观测数据生成误差控制及模型选择

    #region 观测误差控制开关
    /// <summary>
    /// 观测数据生成误差控制开关，结构体定义
    /// </summary>
    public struct ObsErrFlag
    {
        /// <summary>
        /// 卫星钟差开关，true：考虑；false：不考虑
        /// </summary>
        public bool IsSatClk;

        /// <summary>
        /// 接收机钟差开关
        /// </summary>
        public bool IsStaClk;

        /// <summary>
        /// 电离层开关
        /// </summary>
        public bool IsIion;

        /// <summary>
        /// 对流层开关
        /// </summary>
        public bool IsItro;

        /// <summary>
        /// 多路径开关
        /// </summary>
        public bool IsImul;

        /// <summary>
        /// 相对论效应开关
        /// </summary>
        public bool IsIrel;

        /// <summary>
        /// 相位中心偏移误差开关
        /// </summary>
        public bool IsIoff;

        /// <summary>
        /// 随机误差开关
        /// </summary>
        public bool IsIran;
    }
   

    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class ObsErrFlagClass
    {
        /// <summary>
        /// 卫星钟差开关，true：考虑；false：不考虑
        /// </summary>
        private bool _IsSatClk;

        [XmlAttribute, DescriptionAttribute("卫星钟差开关")]
        public bool IsSatClk
        {
            get { return _IsSatClk; }
            set { _IsSatClk = value; }
        }

        /// <summary>
        /// 接收机钟差开关
        /// </summary>
        private bool _IsStaClk;

        [XmlAttribute, DescriptionAttribute("接收机钟差开关")]
        public bool IsStaClk
        {
            get { return _IsStaClk; }
            set { _IsStaClk = value; }
        }

        /// <summary>
        /// 电离层开关
        /// </summary>
        private bool _IsIion=true;

        [XmlAttribute, DescriptionAttribute("电离层误差开关")]
        public bool IsIion
        {
            get { return _IsIion; }
            set { _IsIion = value; }
        }

        /// <summary>
        /// 对流层开关
        /// </summary>
        private bool _IsItro = true;

        [XmlAttribute, DescriptionAttribute("对流层误差开关")]
        public bool IsItro
        {
            get { return _IsItro; }
            set { _IsItro = value; }
        }

        /// <summary>
        /// 多路径开关
        /// </summary>
        private bool _IsImul;

        [XmlAttribute, DescriptionAttribute("多路径开关")]
        public bool IsImul
        {
            get { return _IsImul; }
            set { _IsImul = value; }
        }

        /// <summary>
        /// 相对论效应开关
        /// </summary>
        private bool _IsIrel;

        [XmlAttribute, DescriptionAttribute("相对论效应开关")]
        public bool IsIrel
        {
            get { return _IsIrel; }
            set { _IsIrel = value; }
        }

        /// <summary>
        /// 相位中心偏移误差开关
        /// </summary>
        private bool _IsIoff;

        [XmlAttribute, DescriptionAttribute("相位中心偏移误差开关")]
        public bool IsIoff
        {
            get { return _IsIoff; }
            set { _IsIoff = value; }
        }

        ///// <summary>
        ///// 随机误差开关
        ///// </summary>
        //private bool _IsIran;

        //[XmlAttribute, DescriptionAttribute("随机误差开关")]
        //public bool IsIran
        //{
        //    get { return _IsIran; }
        //    set { _IsIran = value; }
        //}

        public ObsErrFlag ConvertToStruct()
        {
            ObsErrFlag newObsErrFlag = new ObsErrFlag();
            newObsErrFlag.IsIion = this._IsIion;
            newObsErrFlag.IsImul = this._IsImul;
            newObsErrFlag.IsIoff = this._IsIoff;
           // newObsErrFlag.IsIran = this._IsIran;
            newObsErrFlag.IsIrel = this._IsIrel;
            newObsErrFlag.IsItro = this._IsItro;
            newObsErrFlag.IsSatClk = this._IsSatClk;
            newObsErrFlag.IsStaClk = this._IsStaClk;
            return newObsErrFlag;
        }


        public override string ToString()
        {
            return string.Empty; 
        }


    }


    #endregion

    #region 观测误差模型配置

    #region 钟差模型配置
    /// <summary>
    /// 卫星钟差模型
    /// </summary>
    public enum ESatClkModelType
    {
        多项式模型,
        不考虑,
    }

    /// <summary>
    /// 用户钟差模型
    /// </summary>
    public enum EStaClkModelType
    {
        多项式模型,
        不考虑,
    }
    #endregion

    #region 电离层配置
    /// <summary>
    /// 电离层延迟映射模型
    /// </summary>
    public enum EIonMappingModelType
    {
        电离层映射函数,
    }

    /// <summary>
    /// 电离层延迟改正模型
    /// </summary>
    public enum EIonModelType
    {
        EightParam,
        DoubleFre,
        不考虑,
    }

    /// <summary>
    /// 电离层延迟改正模型，用于观测数据生成
    /// </summary>
    public enum EIonModelTypeObs
    {
        十五阶球谐模型,
        全球格网模型,
        不考虑,
    }
    #endregion 电离层配置

    #region 对流层配置

    #region 气象参数
    /// <summary>
    /// 获取气象参数方式
    /// </summary>
    public enum EWayToGetMeteorological
    {
        /// <summary>
        /// 利用SHAO模型计算
        /// </summary>
        EGNOSModel,

        /// <summary>
        /// 用户输入气象参数
        /// </summary>
        用户输入,
    }


    #endregion

    /// <summary>
    /// 对流层延迟计算模型
    /// </summary>
    public enum ETroModelType
    {
        Hopfield,
        ImprovedHopfield,
        Saastamoinen,
        不考虑,
    }

    /// <summary>
    /// 对流层配置
    /// </summary>
    public struct TroSet
    {
        /// <summary>
        /// 气象参数配置
        /// </summary>
        public EWayToGetMeteorological WayToGetMeteorological;

        /// <summary>
        /// 对流层模型选择
        /// </summary>
        public ETroModelType TroModel;
    }

    /// <summary>
    /// 对流层气象参数
    /// </summary>
    public struct MeteorologicalsParam 
    {
	    public double Temperature;		//温度(单位：oC)	
	    public double Pressure;			//大气压力(mbar)	
	    public double RelHumidity;		//相对湿度(%)	
	    public double SatVaporPressure;	//纯水平液面饱和水气压        
	    public double D_Trop;			//对流层温度下降率 
	    public double LeanVaporPressure;//水汽偏压

        public MeteorologicalsParamClass ToClass()
        {
            MeteorologicalsParamClass ret = new MeteorologicalsParamClass();
            ret.Temperature = this.Temperature;
            ret.Pressure = this.Pressure;
            ret.RelHumidity = this.RelHumidity;
            ret.SatVaporPressure = this.SatVaporPressure;
            ret.D_Trop = this.D_Trop;
            ret.LeanVaporPressure = this.LeanVaporPressure;
            return ret;
        }
    };

    /// <summary>
    /// 对流层气象参数
    /// </summary>
   [TypeConverter(typeof(ExpandableObjectConverter))]  
    public class MeteorologicalsParamClass
    {
        private double _Temperature = 15;		//温度(单位：oC)	
        private double _Pressure = 1013.25;			//大气压力(mbar)	
        private double _RelHumidity = 50;		//相对湿度(%)	
        private double _SatVaporPressure = 0.00204;	//纯水平液面饱和水气压
        private double _D_Trop = -6.81;			//对流层温度下降率 
        private double _LeanVaporPressure = 0.00204;//水汽偏压

        [XmlAttribute, DescriptionAttribute("温度(单位：oC)"), PropertyOrder(1)]
        public double Temperature
        {
            get { return _Temperature; }
            set { _Temperature = value; }
        }

        [XmlAttribute, DescriptionAttribute("大气压力(单位：mbar)"), PropertyOrder(2)]
        public double Pressure
        {
            get { return _Pressure; }
            set { _Pressure = value; }
        }

        [XmlAttribute, DescriptionAttribute("相对湿度(单位:%)"), PropertyOrder(3)]
        public double RelHumidity
        {
            get { return _RelHumidity; }
            set { _RelHumidity = value; }
        }

        [XmlAttribute, DescriptionAttribute("纯水平液面饱和水气压"), PropertyOrder(4)]
        public double SatVaporPressure
        {
            get { return _SatVaporPressure; }
            set { _SatVaporPressure = value; }
        }

        [XmlAttribute, DescriptionAttribute("对流层温度下降率"), PropertyOrder(5)]
        public double D_Trop
        {
            get { return _D_Trop; }
            set { _D_Trop = value; }
        }

        [XmlAttribute, DescriptionAttribute("水汽偏压"), PropertyOrder(6)]
        public double LeanVaporPressure
        {
            get { return _LeanVaporPressure; }
            set { _LeanVaporPressure = value; }
        }

        public override string ToString()
        {
            return "MeteorologicalsParam";
        }

        public MeteorologicalsParam ToStruct()
        {
            MeteorologicalsParam ret;
            ret.Temperature = this.Temperature;
            ret.Pressure = this.Pressure;
            ret.RelHumidity = this.RelHumidity;
            ret.SatVaporPressure = this.SatVaporPressure;
            ret.D_Trop = this.D_Trop;
            ret.LeanVaporPressure = this.LeanVaporPressure;
            return ret;
        }
    };

    /// <summary>
    /// 对流层计算输入
    /// </summary>
    public struct CalTro_Input
    {
        public MeteorologicalsParam Tro;
        [MarshalAs(UnmanagedType.ByValArray,SizeConst=3)]
        public double[] SatECFPos; 	//卫星位置
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public double[] UsePos;       //用户位置
    }; 

    #endregion 对流层配置

    #region 多路径配置
    /// <summary>
    /// 多路径模型
    /// </summary>
    public enum EMulModelType
    {
        常量模型,
        不考虑,
    }

    #endregion 多路径配置

    #region 相对论效应模型配置
    /// <summary>
    /// 相对论效应计算模型
    /// </summary>
    public enum ERelModelType
    {
        自定义模型,
        不考虑,
    }

    #endregion 相对论效应模型配置

    #region 相位中心偏移模型配置
    /// <summary>
    /// 相位中心偏移误差计算模型
    /// </summary>
    public enum EOffModelType
    {
        自定义模型,
        不考虑,
    }
    #endregion 相位中心偏移模型配置

    #region 随机噪声设置
    /// <summary>
    /// 随机噪声类型
    /// </summary>
    public enum ERanType
    {
        白噪声模型,
    }

    /// <summary>
    /// 噪声量级
    /// </summary>
    public struct RanOrder
    {
        /// <summary>
        /// 生成伪距时考虑的随机噪声量级
        /// </summary>
        public double PseudoRanOrder;

        /// <summary>
        /// 生成载波相位时考虑的随机噪声量级
        /// </summary>
        public double CarrywaveRanOrder;
    }


    /// <summary>
    /// 随机噪声设置
    /// </summary>
    public struct RanSet
    {
        /// <summary>
        /// 随机噪声类型
        /// </summary>
        public ERanType Ran_Type;

        /// <summary>
        /// 随机噪声量级
        /// </summary>
        public RanOrder Ran_Order;
    }

    #endregion 随机噪声设置

    #endregion 观测误差模型配置

    #endregion 观测数据生成误差控制及模型选择

    #region 星地下行输出的观测数据
    [StructLayout(LayoutKind.Sequential)]
    public struct ObsReceiverInPut
    {
        public UTCTime CurTime;						     	//观测值生成时间
        public int SatID;						            //卫星编号	

        /// <summary>
        /// 0:ECI_pos 1:ECI_(pos+vel)， 下行观测时为卫星，上行观测时为地面站
        /// </summary>
        public int SendPosFlag;                             
        public int StaID;							        //测站编号
        public NodePosVel ReceiverPos;					    //接收机位置
        public double Freq;                                 //信号频率
       
        /// <summary>
        /// 连续10个发射星的位置信息信息，下行观测时为卫星，上行观测时为地面站（ECI）
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
        public NodePosVel[] SendPos;	                      

        /// <summary>
        /// 噪声量级， DeltRanThH[0]为伪距噪声量级， DeltRanThH[1]位载波相位噪声量级
        /// </summary>
        //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        //public double[] DeltRanThH;                         

        /// <summary>
        /// 观测误差，ObsDelay[0]为伪距误差，ObsDelay[1]位载波相位误差,以米为单位
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public double[] ObsErr;                             
        
    }

    
    /// <summary>
    /// 监测站单接收机对单颗卫星的单频点观测数据
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct SingleSatObs
    {
        /// <summary>
        /// 伪距
        /// </summary>
        public double A_Pseudo_writein;

        /// <summary>
        /// 载波相位测量值
        /// </summary>
        public double A_Carri_writein;

        /// <summary>
        /// 多普勒频移
        /// </summary>
        public double DoplShift;

        /// <summary>
        /// 伪距一阶变率
        /// </summary>
        public double DotPseudo;
    };

    /// <summary>
    /// 锚固站/注入站观测数据输出
    /// </summary>
    public struct UpDownObsOutPut
    {
        /// <summary>
        /// 周
        /// </summary>
        public int WN;

        /// <summary>
        /// 周内秒
        /// </summary>
        public double Sow;

        /// <summary>
        /// 接收ID
        /// </summary>
        public int RecID;

        /// <summary>
        /// 发送ID
        /// </summary>
        public int SndID;

        /// <summary>
        /// 接收机与单颗卫星的观测值输出
        /// </summary>
        public ObsReceiverOutput ObsOutPut;   
    };



    /// <summary>
    /// 接收机对单颗卫星的观测值输出
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct ObsReceiverOutput
    {
        public UTCTime CurTime;						//观测值生成时间
        /// <summary>
        /// 接收机ID号
        /// </summary>
        public int ReceiverID;

        /// <summary>
        /// 卫星编号
        /// </summary>
        public int SatID;

        /// <summary>
        /// 对该可见卫星/地面站的观测数据
        /// </summary>
        public SingleSatObs SatObs;

        /// <summary>
        /// 观测值生成时刻发射星的位置，下行时指卫星，上行时指地面站
        /// </summary>
        public NodePosVel SendPV;
    };

    /// <summary>
    /// 单颗卫星的观测数据误差，电离层、对流层、相位中心偏移
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct ObsErrOutput
    {
        /// <summary>
        /// 卫星好
        /// </summary>
        public int SatID;
        /// <summary>
        /// 对流层误差
        /// </summary>
        public double DeltTro;
        /// <summary>
        /// 相位中心偏移
        /// </summary>
        public double DeltOff;
        /// <summary>
        /// 电离层
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public double[] DeltIon;
    }
    #endregion 星地下行输出的观测数据
}
